package io.renren.modules.wcs.service.impl;

import io.renren.modules.ioserver.IOServerService;
import io.renren.modules.wcs.constant.QGSConstant;
import io.renren.modules.wcs.entity.CargoArg;
import io.renren.modules.wcs.entity.DDJJobEntity;
import io.renren.modules.wcs.enums.IOServerEnum;
import io.renren.modules.wcs.taskPool.*;
import io.renren.modules.wcs.service.DDJService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.LinkedList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * @Author: 蔡翔
 * @Date: 2019/10/16 16:01
 * @Version 1.0
 */
@Service
public class DDJServiceImpl implements DDJService {

    //如果要 用@Autowired 把 单独一个 类 传入一个new出来线程，是不可行的的，
    //因为@Autowired是多处共用一个，传入单独线程，可能会存在线程安全问题。所以不可以
    @Autowired
    private IOServerService ioServerServices;

    //这里ioserverService不需要静态的，每一个nio线程，重新new 一个都没有关系。
    IOServerService ioServerService = new IOServerService();

    private static final Logger logger = LoggerFactory.getLogger(DDJServiceImpl.class);

    // new - begin
    public static DDJGetCargoArgRunnable<CargoArg> cargoArgRunnable = new DDJGetCargoArgRunnable<>();
    //public static DDJCreateTaskRunnable<Integer> createTaskRunnable = new DDJCreateTaskRunnable<>();

    //任务队列，是用来取消当前队列的  (final类不能被继承),,现在只是暂时来用 停止当前任务。
    private final LinkedList<DDJCreateTaskRunnable<Integer>> taskQueue = new LinkedList<>();

    @Override
    public Integer modifyCargoArg(CargoArg cargoArg) {
        Short cargoW = cargoArg.getCargoWeight();
        Short cargoH = cargoArg.getCargoHeight();
        Integer integer1 = -99;
        Integer integer2 = -99;

        try {
            integer1 = ioServerService.setTagValue(IOServerEnum.Cargo_Weight.getCollectionPointName(), cargoW.toString(), 1);
            integer2 = ioServerService.setTagValue(IOServerEnum.Cargo_Height.getCollectionPointName(), cargoH.toString(), 1);
        } catch (Exception e) {
            return -1;
        }
        if (integer1 == 0 && integer2 == 0) {
            return 1;
        } else {
            return 0;
        }
    }

    @Override
    public Integer modifyDeviceStatus(CargoArg cargoArg) {
        Short cargoW = cargoArg.getCargoWeight();
        Integer integer1 = -99;

        try {
            integer1 = ioServerService.setTagValue(IOServerEnum.Device_Status.getCollectionPointName(), cargoW.toString(), 5);
        } catch (Exception e) {
            return -1;
        }
        if (integer1 == 0) {
            return 1;
        } else {
            return 0;
        }
    }

    @Override
    public Integer modifyDeviceLstart(CargoArg cargoArg) {
        Short cargoW = cargoArg.getCargoWeight();
        Integer integer1 = -99;

        try {
            integer1 = ioServerService.setTagValue(IOServerEnum.L_Start.getCollectionPointName(), cargoW.toString(), 4);

        } catch (Exception e) {
            return -1;
        }
        if (integer1 == 0) {
            return 1;
        } else {
            return 0;
        }
    }

    @Override
    public Integer modifyCargoFirstHeight(CargoArg cargoArg) {
        Short cargoW = cargoArg.getCargoWeight();
        Integer integer1 = -99;

        try {
            integer1 = ioServerService.setTagValue(IOServerEnum.Cargo_First_Height.getCollectionPointName(), cargoW.toString(), 1);

        } catch (Exception e) {
            return -1;
        }
        if (integer1 == 0) {
            return 1;
        } else {
            return 0;
        }
    }

    @Override
    public Integer stopCurrentTask() {
        taskQueue.removeFirst().shutdownGreaceful();
        return 1;
    }

    /**
     * 返回值:
     * -1 代表 IOServer 写入异常
     * -2 代表 堆垛机在执行任务途中 出现故障。
     * -3 代表 重置称重plc 失败
     * 1 代表 堆垛机执行成功
     * 2 代表 重置任务失败。
     * 3 代表 分发任务失败
     *
     * status : work
     **/
    @Override
    public Integer sendTaskAndListening(DDJJobEntity ddjJobEntity) {

        //public static DDJCreateTaskRunnable<Integer> createTaskRunnable = new DDJCreateTaskRunnable<>();
        //DDJCreateTaskRunnable<Integer> createTaskRunnable = new DDJCreateTaskRunnable<>();
        //入库 == 1
        Integer result = -99;
        if(ddjJobEntity.getType()==1){
            DDJWarehousingRunnable<Integer> warehousingRunnable = new DDJWarehousingRunnable<>();
            // 写 依据plc 货物 高度和重量 分配合适厂库位置=====结束
            warehousingRunnable.initialDDJCreateTaskRunnable(ioServerService, ddjJobEntity);
            Future<?> futureTask;
            synchronized (QGSConstant.LOCK){
                futureTask = QGSThreadPool.executor.submit(warehousingRunnable);
                //taskQueue.addLast(warehousingRunnable);
            }
            Object taskResult = new Object();
            try {
                taskResult = futureTask.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            Integer taskResults = (Integer) taskResult;
            result = taskResults;
        }else if(ddjJobEntity.getType()==2){
            DDJOutOfStockRunnable<Integer> outOfStockRunnable = new DDJOutOfStockRunnable<>();
            // 写 依据plc 货物 高度和重量 分配合适厂库位置=====结束
            outOfStockRunnable.initialDDJCreateTaskRunnable(ioServerService, ddjJobEntity);
            Future<?> futureTask;
            synchronized (QGSConstant.LOCK){
                futureTask = QGSThreadPool.executor.submit(outOfStockRunnable);
                //taskQueue.addLast(warehousingRunnable);
            }
            Object taskResult = new Object();
            try {
                taskResult = futureTask.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            Integer taskResults = (Integer) taskResult;
            result = taskResults;
        }
        return result;
    }
}
